package com.cn.lp.openapi.processor;

import com.cn.lp.openapi.base.ParameterExpander;
import com.cn.lp.openapi.param.RequestParam;
import feign.MethodMetadata;
import feign.Param;
import feign.Util;
import org.springframework.cloud.openfeign.annotation.RequestHeaderParameterProcessor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * RequestHeaderParam注解处理器
 * 通过Expander触发RequestParam的initMap方法，把对象属性注入Map中，然后通过headerMapIndex触发Map转param
 */
public class RequestHeaderParamParameterProcessor extends RequestHeaderParameterProcessor {

    private boolean encode = true;

    private Charset charset = Util.UTF_8;

    public static RequestHeaderParamParameterProcessor build(boolean encode, Charset charset) {
        RequestHeaderParamParameterProcessor requestHeaderParamParameterProcessor = new RequestHeaderParamParameterProcessor();
        requestHeaderParamParameterProcessor.encode = encode;
        requestHeaderParamParameterProcessor.charset = charset;
        return requestHeaderParamParameterProcessor;
    }

    @Override
    public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
        int parameterIndex = context.getParameterIndex();
        Class<?> parameterType = method.getParameterTypes()[parameterIndex];
        MethodMetadata data = context.getMethodMetadata();
        if (RequestParam.class.isAssignableFrom(parameterType)) {
            context.setParameterName("s");
            Map<Integer, Param.Expander> indexToExpander= data.indexToExpander();
            indexToExpander.put(parameterIndex, ParameterExpander.build(encode, charset));
            data.indexToEncoded().put(parameterIndex, Boolean.FALSE);
            MethodMetadata metadata = context.getMethodMetadata();
            if (metadata.headerMapIndex() == null) {
                metadata.headerMapIndex(parameterIndex);
            }
            return true;
        }
        return super.processArgument(context, annotation, method);
    }
}
